package com.xyy.saas.payment.payment.core.adapter;

import com.alibaba.fastjson.JSONObject;
import com.xyy.saas.payment.adpater.config.BankConfigManager;
import com.xyy.saas.payment.common.enums.AmountDirectionType;
import com.xyy.saas.payment.common.enums.AmountTypeEnum;
import com.xyy.saas.payment.common.exception.PaymentException;
import com.xyy.saas.payment.cores.enums.BusinessIdTypeEnum;
import com.xyy.saas.payment.cores.enums.BusinessOrderTypeEnum;
import com.xyy.saas.payment.cores.vo.SeparateAccountFromUserVo;
import com.xyy.saas.payment.service.PayAccountService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@Slf4j
public class AccountAdapter {
    @Resource
    private BankConfigManager bankConfigManager;
    @Resource
    private PayAccountService payAccountService;

    /**
     * 组装转账参数
     * @param businessOrderType
     * @param businessOrderNo
     * @param type
     * @param amount
     * @return
     */
    public SeparateAccountFromUserVo buildSeparateAccount(String businessOrderType, String accountId,
        String businessOrderNo, AmountTypeEnum type, Integer amount) throws PaymentException
    {
        AmountDirectionType direction = getAmountDirectionTyp(businessOrderType, type, amount);
        SeparateAccountFromUserVo account = new SeparateAccountFromUserVo();
        account.setBusinessOrderNo(getBusinessOrderNo(type, businessOrderNo));
        account.setBusinessIdType(businessOrderType);
        account.setBusinessUserIdOut(AmountDirectionType.ADD == direction ?
                getAccount(businessOrderType, type) : payAccountService.getBusinessUserIdByAccountId(accountId));
        account.setBusinessUserIdIn(AmountDirectionType.ADD == direction ?
                payAccountService.getBusinessUserIdByAccountId(accountId) : getAccount(businessOrderType, type));


        // 退款专户是固定业务线
        if(AmountTypeEnum.REFUND_AMOUNT == type) {
            if(AmountDirectionType.ADD == direction) {
                account.setBusinessIdTypeOut(BusinessIdTypeEnum.EC_SELF_SUPPORT.getType());
            }
            else {
                account.setBusinessIdTypeIn(BusinessIdTypeEnum.EC_SELF_SUPPORT.getType());
            }
        }

        /**
         * 金额需要是正数
         */
        account.setAmount(Math.abs(amount));
        account.setInvoker(StringUtils.EMPTY);
        account.setBusinessType(BusinessOrderTypeEnum.getBusinessType(businessOrderType));
        account.setBusinessOrderType(businessOrderType);
        account.setExtra(getExtra(type, direction));
        log.info("AccountAdapter#buildSeparateAccount account={}", JSONObject.toJSONString(account));
        return account;
    }

    /**
     * 判断资金方法
     * @param businessOrderType
     * @param type
     * @param amount
     * @return
     */
    public AmountDirectionType getAmountDirectionTyp(String businessOrderType, AmountTypeEnum type, Integer amount) throws PaymentException  {
        if(BusinessOrderTypeEnum.EC_POP.getType().equals(businessOrderType)) {
            switch(type) {
                case BALANCE_PAY_AMOUNT:
                case DIRECT_PAY_AMOUNT:
                    return AmountDirectionType.ADD;
                case BALANCE_REFUND_AMOUNT:
                case REFUND_AMOUNT:
                    return AmountDirectionType.SUBTRACT;
                case PLATFORM_DISCOUNT_AMOUNT:
                    return amount > NumberUtils.INTEGER_ZERO ? AmountDirectionType.ADD : AmountDirectionType.SUBTRACT;
                case BROKERAGE_AMOUNT:
                    return amount > NumberUtils.INTEGER_ZERO ?  AmountDirectionType.SUBTRACT : AmountDirectionType.ADD;
                default:
                    throw new PaymentException("Profit sharing AmountTypeEnum not support with " + type.name());
            }
        }

        throw new PaymentException("Profit sharing account not support with " + businessOrderType);
    }

    /**
     * 获取转账单号
     * @param type
     * @param businessOrderNo
     * @return
     */
    private String getBusinessOrderNo(AmountTypeEnum type, String businessOrderNo) {
        return businessOrderNo+ "_" + type.name().toLowerCase();
    }

    /**
     * 获取账户
     * @param type
     * @return
     */
    private String getAccount(String businessOrderType, AmountTypeEnum type) throws PaymentException {
        return bankConfigManager.getProfitSharingAccount(businessOrderType, type);
    }

    /**
     * 转账附加信息
     * @param type
     * @param direction
     * @return
     */
    private String getExtra(AmountTypeEnum type, AmountDirectionType direction) {
        return type.name() + "_" + direction.name();
    }
}
